import * as d3 from 'd3'
var LineChart = {
  data: '',
  divId: '',
  xLabel: '',
  yLabel: '',
  title: '',
  itemsName: [],
  lineChart: {},
  color: d3.scaleOrdinal(d3.schemeCategory10),
  draw: function () {
    this.initChart()
    this.initAxis()
    this.drawLabel()
    this.drawLegend()
    this.drawLine()
  },
  update: function () {
    this.drawLegend()
    this.drawLine()
  },
  initChart: function () {
    this.lineChart.padding = {
      left: 20,
      right: 50,
      top: 20,
      bottom: 20
    }
    this.lineChart.divHeight = document.getElementById(this.divId).offsetHeight -
      this.lineChart.padding.top -
      this.lineChart.padding.bottom
    this.lineChart.divWidth = document.getElementById(this.divId).offsetWidth -
      this.lineChart.padding.left -
      this.lineChart.padding.right

    this.lineChart.svg = d3
      .select('#' + this.divId)
      .append('svg')
      .attr('width', this.lineChart.divWidth +
        this.lineChart.padding.left +
        this.lineChart.padding.right
      )
      .attr('height', this.lineChart.divHeight +
        this.lineChart.padding.top +
        this.lineChart.padding.bottom
      )
      .attr('class', 'svg_lineChart')
  },
  initAxis: function () {
    this.lineChart.xScale = d3.scaleLinear()
      .domain([0, this.data[0].length - 1])
      .range([this.lineChart.padding.left, this.lineChart.divWidth])

    let maxNum = this.data.map(function (d) {
      return d3.max(d)
    })
    this.lineChart.yScale = d3.scaleLinear()
      .domain([0, d3.max(maxNum)])
      .range([this.lineChart.divHeight, this.lineChart.padding.top])

    this.lineChart.xAxis = d3
      .axisBottom()
      .scale(this.lineChart.xScale)
      .ticks(this.data[0].length)
    //   .tickFormat((d) => 2015 + parseInt(d))
    this.lineChart.yAxis = d3.axisLeft().scale(this.lineChart.yScale)

    this.lineChart.svg
      .append('g')
      .attr('class', 'xAxis')
      .attr('transform', 'translate(0,' + this.lineChart.divHeight + ')')
      .call(this.lineChart.xAxis)
    this.lineChart.svg
      .append('g')
      .attr('class', 'yAxis')
      .attr('transform', 'translate(' + this.lineChart.padding.left + ')')
      .call(this.lineChart.yAxis)
  },
  drawLine: function () {
    let t = d3.transition()
      .duration(1000)
      .ease(d3.easeLinear)

    this.lineChart.pathLine = d3.line()
      .curve(d3.curveBasis)
      .x((d, i) => {
        return this.lineChart.xScale(i)
      })
      .y((d) => this.lineChart.yScale(d))

    let lines = this.lineChart.svg
      .selectAll('.line')
      .data(this.data)

    let lineEnter = lines.enter()
      .append('path')
      .attr('class', 'line')
      .attr('d', this.lineChart.pathLine)
      .style('stroke-dasharray', function (d) {
        return this.getTotalLength()
      })
      .style('stroke-dashoffset', function (d) {
        return this.getTotalLength()
      })
      .style('fill', 'none')
      .style('stroke', (d, i) => this.color(i))
    lineEnter.merge(lines)
    // let lineExit
    lines.exit()
      .transition()
      .duration(1000)
      .style('stroke-dashoffset', function (d) {
        return this.getTotalLength()
      })
      .remove()

    this.lineChart.svg.selectAll('.line')
      .transition(t)
      .style('stroke-dashoffset', 0)
  },
  drawLabel: function () {
    // 标题
    this.lineChart.svg
      .append('text')
      .attr('x', this.lineChart.divWidth / 2 - this.title.length)
      .attr('y', this.lineChart.divHeight + this.lineChart.padding.bottom * 1.7)
      .text(this.title)
    // y轴
    this.lineChart.svg
      .append('text')
      .attr('x', this.lineChart.padding.left)
      .attr('y', this.lineChart.padding.top - 5)
      .text(this.yLabel)
    // x轴
    this.lineChart.svg
      .append('text')
      .attr('x', this.lineChart.divWidth + 5)
      .attr('y', this.lineChart.divHeight)
      .text(this.xLabel)
  },
  drawLegend: function () {
    let legendWidth = 15
    let legendHeight = 15
    let legends = this.lineChart.svg
      .selectAll('.legend')
      .data(this.itemsName)
    let legendEnter = legends.enter()
      .append('g')
      .attr('class', 'legend')

    legendEnter.append('rect')
      .attr('x', this.lineChart.divWidth + 5)
      .attr('y', (d, i) => this.lineChart.padding.top + legendHeight * i)
      .attr('width', 0)
      .attr('height', legendHeight - 5)
      .style('fill', (d, i) => this.color(i))

    legendEnter.append('text')
      .attr('x', this.lineChart.divWidth + legendWidth * 1.3 + 5)
      .attr('y', (d, i) => this.lineChart.padding.top + legendHeight * i + legendHeight / 2)
      .text(String)
      .style('font-size', 1e-6)

    let legendUpdate = legendEnter.merge(legends)

    legendUpdate.select('rect')
      .transition()
      .duration(750)
      .attr('width', legendWidth)

    legendUpdate.select('text')
      .transition()
      .duration(750)
      .style('font-size', 10)

    let legendExit = legends.exit()
      .transition()
      .duration(750)
      .remove()

    legendExit.select('rect')
      .attr('width', 0)

    legendExit.select('text')
      .style('stroke-opacity', 1e-6)
  }
}
export {
  LineChart
}
